/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.mlu.jdbc.simple.codegeneration;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.mlu.jdbc.simple.utils.JdbcUtils;
import org.mlu.jdbc.simple.utils.SchemaUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *
 * @author Mlungisi Sincuba
 * @since 1.0
 */
public class CodeUtil {

    private static final Logger logger = LoggerFactory.getLogger(CodeUtil.class);
    
    public static String getPrimaryKey(String tableName, DataSource dataSource) throws SQLException {
        Map<String, Boolean> primaryKeysForTable = SchemaUtil.getPrimaryKeysForTable(dataSource.getConnection(), tableName);
        for (Map.Entry<String, Boolean> entry : primaryKeysForTable.entrySet()) {
            String key = entry.getKey();
            return key;
        }
        return "";
    }
    
    public static String[] toTablesArray(String[] tableNames, String[] tableNamesArray, DataSource dataSource) throws SQLException {
        List<String> tableNamesList;
        if (tableNames == null) {
            logger.debug("Generating classes from all tables on database...");
            tableNamesList = SchemaUtil.getTableNames(dataSource.getConnection(), null);
            tableNamesArray = (String[]) tableNamesList.toArray(new String[tableNamesList.size()]);
        }
        return tableNamesArray;
    }

    public static String getSrcPath(String src, boolean mavenProject) {
        if (src == null) {
            File srcFilePath = new File(".");
            try {
                src = srcFilePath.getCanonicalPath() + File.separator + "src";
                if (mavenProject) {
                    src += File.separator + "main" + File.separator + "java";
                }
            } catch (IOException ex) {
                logger.error("src path not found", ex);
            }
        }
        logger.debug("src = {}", src);
        return src;
    }

    public static String getPackagePath(String src, String packageName) {
        //String domainSrc = src + File.separator + "domain";
        File srcFilePath = new File(src);

        if (!srcFilePath.exists()) {
            logger.debug("Created src path: {}", src);
            srcFilePath.mkdir();
        } else {
            logger.debug("Could not create src path: {}", src);
        }
        logger.debug("src = {}", src);
        if (packageName == null) {
            packageName = ".domain";
        }
        String[] dirs = packageName.split("\\.");

        String s = "";
        for (String path : dirs) {
            logger.debug("path1 {}", s);
            s += File.separator + path;
            logger.debug("path2 {}", s);
            String fullPath = src + s;
            System.out.println("fullPath: " + fullPath);

            File srcPath = new File(fullPath);
            boolean createdPath = srcPath.mkdirs();
            logger.debug("Created path: {}", createdPath);

        }
        String packagePath = packageName.replaceAll("\\.", File.separator);
        packagePath = src + File.separator + packagePath;
        logger.debug("packagePath = {}", packagePath);
        return packagePath;
    }

    public static Map<String, String> attributes(String tableName, StringBuilder toStringFormat, StringBuilder toStringValues, StringBuilder sb, DataSource dataSource) throws SQLException {
        //Attributes
        Map<String, String> columnTypePairForTable = SchemaUtil.getColumnTypePairForTable(dataSource.getConnection(), tableName);
        for (Map.Entry<String, String> entry : columnTypePairForTable.entrySet()) {

            String columnName = entry.getKey();
            String javaType = entry.getValue();
            String propertyName = JdbcUtils.convertUnderscoreNameToPropertyName(columnName);
            toStringFormat.append(propertyName).append("=").append("%s, ");
            toStringValues.append(propertyName).append(", ");
            sb.append("   private ").append(javaType).append(" ").append(propertyName).append(";\n");
        }
        sb.append("\n");
        return columnTypePairForTable;
    }
    
    public static void saveTofile(String packagePath, String className, StringBuilder sb) throws IOException {
        //Save to file
        File packagePathFile = new File(packagePath);
        if (!packagePathFile.exists()) {
            packagePathFile.mkdir();
        }
        String path = packagePathFile.getCanonicalPath();
        logger.debug("path = {}", path);
        String javaFileName = path + File.separator + className + ".java";
        logger.debug("javaFileName = {}", javaFileName);
        File javaFile = new File(javaFileName);
        if (!javaFile.exists()) {
            javaFile.createNewFile();
        }
        BufferedWriter bw = new BufferedWriter(new FileWriter(javaFile));
        bw.write(sb.toString());
        bw.flush();
        bw.close();
    }

    public static String interfaceDeclaration(String tableName, StringBuilder sb) {
        //Class declaration
        String className = JdbcUtils.convertTableNameToClassName(tableName);
        String interfaceName = className + "Dao";
        sb.append("public interface ");
        logger.debug("className is {}", interfaceName);
        sb.append(interfaceName).append(" extends GenericDao<").append(className)
                .append("> {\n\n}");
        return interfaceName;
    }
}
